package cn.wolfcode.shop.seckillserver.web.controller.frontend;

import cn.wolfcode.shop.common.util.CodeMsg;
import cn.wolfcode.shop.common.util.Result;
import cn.wolfcode.shop.member.domain.User;
import cn.wolfcode.shop.util.BaseKeyPrefix;
import cn.wolfcode.shop.redis.RedisService;
import cn.wolfcode.shop.seckillapi.domain.OrderInfo;
import cn.wolfcode.shop.seckillapi.service.ISeckillGoodService;
import cn.wolfcode.shop.seckillapi.service.ISeckillOrderService;
import cn.wolfcode.shop.seckillapi.vo.SeckillOrderVO;
import cn.wolfcode.shop.seckillserver.anno.UserParam;
import cn.wolfcode.shop.seckillserver.redis.SeckillKeyPrefix;
import cn.wolfcode.shop.seckillserver.util.MQConstants;
import cn.wolfcode.shop.seckillserver.util.OrderMessage;
import org.apache.ibatis.annotations.Param;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.Date;
import java.util.concurrent.ConcurrentHashMap;

@RestController
@RequestMapping("/seckillOrder")
public class SeckillOrderController {

    @Autowired
    private ISeckillGoodService seckillGoodService;

    @Autowired
    private ISeckillOrderService seckillOrderService;

    @Autowired
    private RedisService redisService;

    @Autowired
    private RabbitTemplate rabbitTemplate;

    public static ConcurrentHashMap<Long,Boolean> overStock = new ConcurrentHashMap<>();

    /**
     * 创建秒杀订单
     * @param path
     * @param uuid
     * @param goodId
     * @param user
     * @return
     */
    @RequestMapping("/{path}/doSeckill")
    public Result getOrderNo(@PathVariable("path") String path, String uuid, @Param("goodId") Long goodId, @UserParam User user){

        Boolean flad = overStock.get(goodId);
        if (flad != null && flad){
            return Result.error(CodeMsg.STOCK_OVER);
        }

        String oldPath = redisService.get(SeckillKeyPrefix.SECKILL_PATH, user.getId()+":"+goodId, String.class);
        if(oldPath == null||!oldPath.equals(path)){

            return Result.error(CodeMsg.OP_ERROR);

        }

        //判断用户是否登录
        if (user == null) {
            return Result.error(CodeMsg.USER_NO_LOGIN);
        }


        //判断商品是否存在
        SeckillOrderVO seckillOrderVO = seckillGoodService.findById(goodId);
        if (seckillOrderVO == null) {
            return Result.error(CodeMsg.GOOD_NO_INVENTORY);
        }

        //判断下单时间是否在范围内
        if (seckillOrderVO.getStartDate().getTime() - new Date().getTime() >0) {
            return Result.error(CodeMsg.ACTIVITY_NOT_STARTED);
        }

        //判断是否重复下单
        BaseKeyPrefix key = new BaseKeyPrefix(0, "SECKILL_ORDER:");
        String str = redisService.get(key, goodId + ":" + user.getId(), String.class);
        if (str != null) {
            return Result.error(CodeMsg.DOUBLE_ORDERING);
        }

        //库存查询
        BaseKeyPrefix stockKey = new BaseKeyPrefix(0, "SECKILL_GOOD_STOCK");
        Long result = redisService.decr(stockKey,goodId +"");//递减之后的值

        if(result < 0){
            overStock.put(goodId,true);
            return Result.error(CodeMsg.STOCK_OVER);
        }

        //下单操作(发送至消息队列)
        OrderMessage orderMessage = new OrderMessage();
        orderMessage.setGoodId(goodId+"");
        orderMessage.setUserId(user.getId()+"");
        orderMessage.setData(seckillOrderVO);
        orderMessage.setUuid(uuid);

        rabbitTemplate.convertAndSend(MQConstants.ORDER_PEDDING_QUEUE,orderMessage);

        return Result.success("订单操作成功，请等待结果");

    }


    /**
     * 根据订单号 提供订单详情信息
     * @param orderNo
     * @return
     */
    @RequestMapping("/find")
    public Result find(@Param("orderNo") String orderNo){

        OrderInfo orderInfo = seckillOrderService.findByOrderNo(orderNo);

        if (orderInfo == null){
            return Result.error(CodeMsg.ORDERING_ERROR);
        }

        return Result.success(orderInfo);
    }


    /**
     * Redis 初始化订单数据
     * @return
     */
    @RequestMapping("/orderInit")
    public Result orderInit(){

        seckillOrderService.orderInit();

        return Result.success(null);

    }

}
